const baseForm = (()=> {

    function itemDataInit(type, VModel, label){
        let init= {'v-model': VModel};
        let ot = {events: {}, col: 24, fillCol: 0, preFill: 0, labelWidth: '80px', label: label, type: type, afterRender: null, options: null, format: null, validator: null,}
        return {
            placeholder(value){ this.set('placeholder', value); return this; },
            col(value, fill, preFill){ ot.col = value; ot.fillCol = fill || 0; ot.preFill = preFill || 0; return this; },
            validator(value){ ot.validator = value; return this; },
            required(msg){ ot.validator = msg ? msg : true; return this; },
            labelWidth(value){ ot.labelWidth = value; return this; },
            options(options){ ot.options = options; return this; },
            format(format){ ot.format = format; return this; },
            on(event, handler){ ot.events[event] = handler; return this; },
            afterRender(after){ ot.afterRender = after; return this; },
            set(attr, value = ''){ init[attr] = value; return this; },
            getEvents(){ return ot.events;},
            get1(attr, defaultValue){
                if (attr === null) return init;
                return init.hasOwnProperty(attr) ? init[attr] : defaultValue;
            },
            get2(attr, defaultValue){
                if (attr === null) return ot;
                return ot[attr] || defaultValue;
            },
        }
    }

    function submitInit(submitHandler){
        const submitData = {
            type:'submit',
            submitText:"提交",
            submitHandler: submitHandler || function () {
                console.log('submit!');
            },
            resetText: "重置",
            resetHandler: null,
            col: 24,
            fillCol: 0,
            preFill: 0,
            labelWidth: "80px",
            afterRender: null,
        }

        return {
            submitText(text) {submitData.submitText = text; return this;},
            resetText(text) {submitData.resetText = text; return this;},
            resetHandler(handler) {submitData.resetHandler = handler; return this;},
            col(value, fill, preFill){ submitData.col = value; submitData.fillCol = fill || 0; submitData.preFill = preFill || 0; return this; },
            labelWidth(value){ submitData.labelWidth = value; return this; },
            get(attr, defaultValue){
                return attr === null ? submitData : (submitData[attr] || defaultValue);
            },
            get2(attr, defaultValue){
                return this.get(attr, defaultValue)
            },
            get1(attr, defaultValue){
                return null
            },
            afterRender(after){
                submitData.afterRender = after;
                return this;
            }
        }
    }


    const form = () => {
        let items = [];
        let model, attrs = {};

        function makeFormEl(init){
            let formEl = document.createElement('el-form');
            let rowEl = document.createElement('el-row');
            rowEl.setAttribute(":gutter", 5)
            let rules = {};
            items.forEach(item => {
                if (item.get2("type") !== 'custom' && item.get1('v-model')) {
                    const rule = formRulesMaker(item.get2('validator'), item.get2('label'));
                    rule && (rules[item.get1('v-model')] = rule);
                    item.set('v-model', `${model}.${item.get1('v-model')}`);
                }
                if (item.get2('preFill') > 0) {
                    let colEl = document.createElement('el-col');
                    colEl.setAttribute(':span', item.get2('preFill'));
                    rowEl.appendChild(colEl);
                }
                rowEl.appendChild(formItemRender(item, model));
                if (item.get2('fillCol') > 0) {
                    let colEl = document.createElement('el-col');
                    colEl.setAttribute(':span', item.get2('fillCol'));
                    rowEl.appendChild(colEl);
                }
            });
            formEl.setAttribute(":model", model);
            formEl.setAttribute("label-width", '80px');
            formEl.appendChild(rowEl);
            for (let attr in attrs) {
                formEl.setAttribute(attr, attrs[attr]);
            }

            init && init(formEl, rules);
            return formEl;
        }



        return {
            model(modelName){
                model = modelName;
                return this;
            },
            ref(ref){
                this.set('ref', ref)
                return this;
            },
            rules(rules){
                this.set(':rules', rules)
                return this;
            },
            set(attr, value = ''){
                attrs[attr] = value;
                return this;
            },
            addItems(...item){
                items.push(...item)
                return this;
            },
            render(el, init) {
                document.getElementById(el.substring(1)).appendChild(makeFormEl(init));
            },
            getEl(init){
                return makeFormEl(init);
            }
        }
    }

    const formRulesMaker = (validator, label) => {
        if (validator === true) {
            return [{required: true, message: `${label}不能为空`, trigger: 'blur'}];
        }else if(typeof validator === 'string'){
            return [{required: true, message: validator, trigger: 'blur'}];
        }else if(Array.isArray(validator)){
            return validator;
        }else if(typeof validator === 'object'){
            return [validator];
        }else if(typeof validator === 'function'){
            return [{validator: validator, trigger: 'blur'}];
        }
        return null;
    }


    const formItemRender = (itemData, model) => {
        function formItemElMake(el){
            let elItem = document.createElement('el-form-item');
            let elCol = document.createElement('el-col');
            itemData.get2('label') && elItem.setAttribute('label', itemData.get2('label'));
            elItem.setAttribute('label-width', itemData.get2('labelWidth'))
            eventHandle(el);

            for (let key in itemData.get1(null)) {
                if (key === 'v-model' && !itemData.get1('v-model')) {
                    continue;
                }
                el.setAttribute(key, itemData.get1(key));
            }

            let prop = itemData.get1('v-model', '').replace(model + '.', '');
            prop && elItem.setAttribute('prop', prop);
            elItem.appendChild(el)

            if (itemData.get2('afterRender')){
                itemData.get2('afterRender')(elItem);
            }

            elCol.appendChild(elItem);
            elCol.setAttribute(':span', itemData.get2('col', 24));

            return elCol;
        }

        const eventHandle = (el) => {
            for (let event in itemData.getEvents()) {
                const handler = itemData.getEvents()[event];
                el.setAttribute('v-on:' + event, handler);
            }
        }

        const optionsHandle = (el) => {
            let op;
            if (typeof itemData.get2('options') === 'string') {
                op = itemData.get2('options');
            } else {
                op = JSON.stringify(itemData.get2('options'));
            }
            el.setAttribute('v-for', 'item in ' + op);
            el.setAttribute(':value', 'item.value');
            el.setAttribute(':label', 'item.desc');
            let format = itemData.get2('format', "{{ item.desc }}");
            format = typeof format === 'function' ? format() : format;
            el.innerHTML = format;
        }

        const render = {
            input(){
                if (!itemData.get1(":clearable")) {
                    itemData.set(':clearable', "true");
                }

                let el = document.createElement("el-input");
                el.setAttribute('placeholder', itemData.get1('placeholder', '请输入' + itemData.get2('label')));

                return formItemElMake(el);
            },
            password(){
                itemData.set('type', 'password');
                itemData.set(':show-password', itemData.get1(':show-password', 'true'));
                return this.input();
            },
            autocomplete(){
                let el = document.createElement("el-autocomplete");
                if (!itemData.get1(":clearable")) {
                    itemData.set(':clearable', "true");
                }

                return formItemElMake(el);
            },
            textarea(){
                itemData.set('type', 'textarea');
                itemData.set(':rows', itemData.get1(':rows', 5));
                return this.input();
            },
            select(){
                let el = document.createElement("el-select");
                el.setAttribute('placeholder', itemData.get1('placeholder', '请选择'));

                let opEl = document.createElement("el-option");
                optionsHandle(opEl);
                el.appendChild(opEl);

                return formItemElMake(el);
            },
            checkbox(){
                let el = document.createElement("el-checkbox-group");
                let opEl = document.createElement("el-checkbox");
                optionsHandle(opEl);
                el.appendChild(opEl);
                return formItemElMake(el);
            },
            radio(){
                let el = document.createElement("el-radio-group");
                let opEl = document.createElement("el-radio");
                optionsHandle(opEl);
                el.appendChild(opEl);
                return formItemElMake(el);
            },
            datetime(){
                let el = document.createElement("el-date-picker");
                itemData.set('type', itemData.get1('type', 'datetime'));
                itemData.set('placeholder', itemData.get1('placeholder', '请选择时间'));

                return formItemElMake(el);
            },
            date() {
                itemData.set('type', 'date');
                itemData.set('placeholder', "请选择日期");
                return this.datetime();
            },
            custom(){
                let tmp = itemData.get1('v-model'), el;
                if (typeof tmp === 'function'){
                    el = tmp();
                }else{
                    el = document.createElement("el-text");
                    el.append(itemData.get1('v-model'));
                }
                if (!itemData.get2('label')){
                    console.log(23123213123)
                    itemData.labelWidth("10px");
                }
                itemData.set('v-model', null);

                return formItemElMake(el);
            },
            submit() {
                let elItem = document.createElement('el-form-item');
                let elCol = document.createElement('el-col');
                elItem.setAttribute('label-width', itemData.get('labelWidth'))
                const submitEL = document.createElement("el-button");
                submitEL.append(itemData.get('submitText'));
                submitEL.setAttribute('v-on:click', itemData.get('submitHandler'))
                submitEL.setAttribute('type', 'primary')
                elItem.append(submitEL);
                if (itemData.get('resetText')) {
                    const restEL = document.createElement("el-button");
                    restEL.append(itemData.get('resetText'));
                    restEL.setAttribute('v-on:click', itemData.get('resetHandler'))
                    elItem.append(restEL);
                }

                if (itemData.get('afterRender')){
                    itemData.get('afterRender')(elItem);
                }

                elCol.appendChild(elItem);
                elCol.setAttribute(':span', itemData.get('col', 24));

                return elCol;
            }
        }

        return render[itemData.get2('type')]();
    };

    return {
        item: {
            time: (VModel, label) => itemDataInit('time', VModel, label),
            date: (VModel, label) => itemDataInit('date', VModel, label),
            input: (VModel, label) => itemDataInit('input', VModel, label),
            autocomplete: (VModel, label) => itemDataInit('autocomplete', VModel, label),
            textarea: (VModel, label) => itemDataInit('textarea', VModel, label),
            password: (VModel, label) => itemDataInit('password', VModel, label),
            radio: (VModel, label) => itemDataInit('radio', VModel, label),
            select: (VModel, label) => itemDataInit('select', VModel, label),
            upload: (VModel, label) => itemDataInit('upload', VModel, label),
            cascader: (VModel, label) => itemDataInit('cascader', VModel, label),
            checkbox: (VModel, label) => itemDataInit('checkbox', VModel, label),
            datetime: (VModel, label) => itemDataInit('datetime', VModel, label),
            custom: (el, label) => itemDataInit('custom', el, label),
            submit: (submit) => submitInit(submit),
        },
        form: form
    }
})();